import { Service } from 'egg';
import { Op } from 'sequelize';
import { v4 as uuidv4 } from 'uuid';
import TemplateOption from './core/template';

class TemplateService extends Service {
  async findTemplate(
    title: string | undefined,
    page: number,
    pageSize: number
  ) {
    const { rows: foundTemplates, count } = await this.ctx.model.Template.findAndCountAll({
      where: { title: { [Op.like]: `%${title}%` } },
      offset: (page - 1) * pageSize,
      limit: pageSize,
      group: 'Template.id',
      include: [
        {
          model: this.ctx.model.Questionnaire,
          attributes: ['open'],
        },
      ],
    });

    const processedTemplates = foundTemplates.map((template) => {
      const templateValue = template.dataValues;

      return {
        ...templateValue,
        questionnaireLen: templateValue?.Questionnaires?.length ?? 0,
        hasQuestionnaireOpen: templateValue?.Questionnaires?.reduce(
          (pre, cur) => (pre.open || cur.open), false
        ) ?? false
      };
    });

    return { rows: processedTemplates, count: count?.length ?? 0 };
  }

  async createTemplate(
    title: string,
    description: string,
    epilog: string,
    prefixion: string,
    logo: string
  ) {
    const { ctx } = this;

    const result = await ctx.model.transaction(async (t) => {
      const template = await ctx.model.Template.findOne({
        where: { title },
      }, { transaction: t });

      if (template) {
        return undefined;
      }

      const newTemplate = await this.ctx.model.Template.create({
        uuid: uuidv4(),
        title,
        description,
        epilog,
        prefixion,
        logo
      }, { transaction: t });
      return newTemplate;
    });
    return result;
  }

  async updateTemplate(
    uuid: string,
    title: string,
    description: string,
    epilog: string,
    prefixion: string,
    logo: string
  ) {
    const changedTemplate = await this.ctx.model.Template.update({
      title,
      description,
      epilog,
      prefixion,
      logo
    }, { where: { uuid } });
    return changedTemplate;
  }

  async deleteTemplate(
    uuid: string,
  ) {
    const removedTemplate = await this.ctx.model.Template.destroy(
      { where: { uuid } }
    );
    return removedTemplate;
  }

  async findOneTemplate(
    uuid: string,
  ) {
    const foundOneTemplate = await this.ctx.model.Template.findOne(
      { where: { uuid } }
    );
    return foundOneTemplate;
  }

  /**
   * 查询所有 template 会作为选项，返回值按照首个文字拼音分组
   * @param title 标题
   */
  async showOptionList(
    title: string,
    attachAll?: boolean
  ) {
    const { ctx } = this;

    const allTemplate = await ctx.model.Template.findAll({
      where: { title: { [Op.like]: `%${title}%` } },
      attributes: ['uuid', 'title'],
    });

    const groupTemplateByLetter = new TemplateOption(allTemplate, attachAll);

    return groupTemplateByLetter.groupTemplateByLetter;
  }

  // 查看template下是否存在二级问卷
  async findQuestionnaireByUuid(templateUuid: string) {
    const { ctx } = this;

    const result = await ctx.model.transaction(async (t) => {
      const template = await ctx.model.Template.findOne({
        where: { uuid: templateUuid },
        attributes: ['id'],
      }, { transaction: t });

      if (!template) {
        return false;
      }

      const { id } = template;

      const questionnaire = await ctx.model.Questionnaire.count({
        where: { fk_template: id }
      }, { transaction: t });

      return questionnaire === 0;
    });
    return result;
  }
}

export default TemplateService;
